---
title: Исправление ошибок в Effector
description: Исправление ошибок
lang: ru
---

import Tabs from "@components/Tabs/Tabs.astro";
import TabItem from "@components/Tabs/TabItem.astro";
import SideBySide from "@components/SideBySide/SideBySide.astro";

# Исправление ошибок (#troubleshooting)

## Основные ошибки (#common-errors)

### `store: undefined is used to skip updates. To allow undefined as a value provide explicit { skipVoid: false } option` (#store-undefined)

Эта ошибка сообщает вам о том, что вы пытаетесь передать в ваш стор значение `undefined`, что, возможно, является некорректным поведением.

Если вам действительно нужно передать в ваш стор значение `undefined`, то вам надо вторым аргументом в `createStore` передать объект со свойством `skipVoid: false`.

```ts
const $store = createStore(0, {
  skipVoid: false,
});
```

### `no handler used in [effect name]` (#no-handler-used)

Эта ошибка возникает при вызове эффекта без обработчика. Убедитесь, что вы передали обработчик в метод `createEffect` при создании, или позже при использовании метода `.use(handler)`.

### `serialize: One or more stores dont have sids, their values are omitted` (#store-without-sid)

:::info{title="До версии 23.3.0"}
До версии 23.3.0 эта ошибка также известна как: `There is a store without sid in this scope, its value is omitted`.
:::

Эта ошибка часто встречается при работе с SSR, она связана с тем, что у вашего стора отсутствует `сид` (stable id), который необходим для корректной гидрации данных с сервера на клиент.
Чтобы исправить эту проблему вам нужно добавить этот `сид`.<br/>
Сделать это вы можете несколькими способами:

1. Использовать [babel](/ru/api/effector/babel-plugin/) или [SWC](/ru/api/effector/swc-plugin/) плагин, который сделает все за вас
2. Или добавить `сид` в ручную, передав во второй аргумент `createStore` объект со свойством `sid`:

   ```ts
   const $store = createStore(0, {
     sid: "unique id",
   });
   ```

Более подробно [про `sid`, как это работает и зачем это нужно](/ru/explanation/sids).

### `scopeBind: scope not found` (#scope-not-found)

Эта ошибка случается когда скоуп потерялся на каком-то из этапов выполнения и `scopeBind` не может связать событие или эффект с нужным скоупом выполнения.<br/>
Эта ошибка могла быть вызвана:

1. Вы используете режим работы 'без скоупа' и у вас их нет в приложении
2. Ваши [юниты были вызваны вне скоупа](#using-units-without-use-unit)

Возможные решения:

1. Используйте `scopeBind` внутри эффектов:

   ```ts
   const event = createEvent();

   // ❌ - не вызывайте scopeBind внутри колбеков
   const effectFx = createEffect(() => {
     setTimeout(() => {
       scopeBind(event)();
     }, 1111);
   });

   // ✅ - используйте scopeBind внутри эффекта
   const effectFx = createEffect(() => {
     const scopeEvent = scopeBind(event);

     setTimeout(() => {
       scopeEvent();
     }, 1111);
   });
   ```

2. Ваши юниты должны быть вызваны внутри скоупа:
   - При работе с фреймворком используйте `useUnit`
   - Если у вас происходит вызов события или эффекта вне фреймворка, то используйте `allSettled` и передайте нужный `scope` в аргумент

Если того требует ваша реализация, а от ошибки нужно избавиться, то вы можете передать свойство `safe:true` во второй аргумент метода.

```ts
const scopeEvent = scopeBind(event, {
  safe: true,
});
```

### `call of derived event is not supported, use createEvent instead` (#call-of-derived-event-is-not-supported)

Эта ошибка возникает, когда вы пытаетесь вызвать производное событие как функцию. Производные события создаются методами как `.map()`, `.filter()`, `.filterMap()`, а также оператором `sample`.

Чтобы исправить используйте событие созданное через `createEvent`.

### `unit call from pure function is not supported, use operators like sample instead` (#unit-call-from-pure-not-supported)

Эта ошибка возникает, когда вы пытаетесь вызвать события или эффекты из [чистых функций](/ru/explanation/glossary#purity) в Effector:

- **Вызов событий в методах событий**<br/>
  Когда вы пытаетесь вызвать одно событие внутри `.map()`, `.filter()`, `.filterMap()` или `.prepend()` другого события.

- **Вызов событий в обработчиках сторов**<br/>
  При попытке вызвать событие в обработчике [`.on()`](/ru/api/effector/Store#methods-on-trigger-reducer), внутри метода [`.map()`](/ru/api/effector/Store#methods-map-fn), или свойства конфигурации [`updateFilter()`](/ru/api/effector/createStore#createStore-formulae) стора.

- **Вызов событий в функциях `sample`**<br/>
  При вызове события в функции `fn` или `filter` оператора `sample`.

Как исправить: Вместо вызова событий в чистых функциях используйте декларативные операторы, например `sample`.

## Частые проблемы (#gotchas)

### `sample.fn` не сужает тип, который приходит из `sample.filter` (#sample-types-error)

Частая проблема с типизацией `sample` происходит когда мы делаем проверку в `filter` на что-то, но не получаем необходимый тип в `fn`. Чтобы это исправить вы можете добавить [предикаты типов](/ru/essentials/typescript#typing-sample-filter-and-fn) или использовать [`effector-action`](https://github.com/AlexeyDuybo/effector-action) билблиотеку, которая поможет проще работать с условными типами:

<SideBySide>
<Fragment slot="left">

```tsx wrap data-height="full"
import { sample } from "effector";

const messageSent = createEvent<Message>();
const userText = createEvent<string>();

sample({
  clock: messageSent,
  filter: (msg: Message): msg is UserMessage => msg.kind === "user",
  fn: (msg) => msg.text,
  target: userText,
});
```

</Fragment>
<Fragment slot="right">

```tsx wrap data-height="full"
import { createAction } from "effector-action";

const userText = createEvent<string>();

const messageSent = createAction({
  target: userText,
  fn: (userText, msg: Message) => {
    if (msg.kind === "user") {
      userText(msg.txt);
    }
  },
});
```

</Fragment>
</SideBySide>

### Мое состояние не изменилось (#my-state-not-changed)

Если ваше состояние не изменилось, то скорее всего вы [работаете со скоупами](/ru/advanced/work-with-scope) и в какой-то момент [активный скоуп потерялся](/ru/guides/scope-loss) и ваш юнит выполнился в глобальной области.<br/>

Типичные места, где это проявляется:

- `setTimeout` / `setInterval`
- `addEventListener`
- [`WebSocket`](/ru/guides/websocket-integration)
- [прямой вызов промисов в эффектах](/ru/advanced/work-with-scope#scope-rules)
- сторонние библиотеки с асинхронными API или колбэки.

**Решение**: [Привяжите ваше событие или эффект к текущему скоупу при помощи `scopeBind`](/ru/guides/scope-loss#how-to-fix-scope-loss):

<SideBySide>
<Fragment slot="left">

```tsx wrap data-border="good" data-height="full" mark={6} "scopedEvent"
// ✅ все отработает корректно

const event = createEvent();

const effectFx = createEffect(() => {
  const scopedEvent = scopeBind(event);

  setTimeout(() => {
    scopedEvent();
  }, 1000);
});
```

</Fragment>
<Fragment slot="right">

```tsx wrap data-border="bad" data-height="full"
// ❌ событие вызовется в глобальном скоупе

const event = createEvent();

const effectFx = createEffect(() => {
  setTimeout(() => {
    event();
  }, 1000);
});
```

</Fragment>
</SideBySide>

#### Использование юнитов без `useUnit` (#using-units-without-use-unit)

Если вы используете события или эффекты во фреймворках без использования хука `useUnit`, что может также повлиять на [потерю скоупа](/ru/guides/scope-loss).<br/>
Чтобы исправить это поведение передайте нужный юнит в `useUnit` хук и используйте возвращаемое значение:

<SideBySide>
<Fragment slot="left">

```tsx wrap data-border="good" data-height="full" "useUnit"
// ✅ использование хука

import { event } from "./model.js";
import { useUnit } from "effector-react";

const Component = () => {
  const onEvent = useUnit(event);

  return <button onClick={() => onEvent()}>click me</button>;
};
```

</Fragment>
<Fragment slot="right">

```tsx wrap data-border="bad" data-height="full"
// ❌ прямой вызов юнита

import { event } from "./model.js";

const Component = () => {
  return <button onClick={() => event()}>click me</button>;
};
```

</Fragment>
</SideBySide>

:::info{title="Информация"}
[Использования хука `useUnit` является рекомендованным способом работы](/ru/guides/best-practices#use-unit) с юнитами.
:::

## Не нашли ответ на свой вопрос ? (#community)

Если вы не нашли ответ на свой вопрос, то вы всегда можете задать сообществу:

- [RU Telegram](https://t.me/effector_ru)
- [EN Telegram](https://t.me/effector_en)
- [Discord](https://discord.gg/t3KkcQdt)
- [Reddit](https://www.reddit.com/r/effectorjs/)
